package saves;

import java.io.Serializable;
import java.util.ArrayList;
import saves.items.Item;

/**
 *
 * @author Luan
 */
public class Inventory implements Serializable {
    private static final long serialVersionUID = 1L;
    
    private ArrayList<ItemEx> inventario;
    private float invMass, invVolume;
    private double money;
    private float volumeLimit;
    
    private Inventory() {}

    public Inventory(ArrayList<ItemEx> inventario, double money, float volumeLimit) {
        this.inventario = inventario;
        recalculateMassVolume();
        this.money = money;
        this.volumeLimit = volumeLimit;
        
        if (invVolume > volumeLimit)
            throw new IllegalArgumentException("The inventory items given do not fit this volume limit.");
    }
    
    private void recalculateMassVolume() {
        invMass = invVolume = 0;
        for (int i = 0; i < this.inventario.size(); i++) {
            invMass += this.inventario.get(i).getItem().getMassa();
            invVolume += this.inventario.get(i).getItem().getVolume();
        }
    }

    public float getMass() {
        return invMass;
    }

    public float getVolume() {
        return invVolume;
    }

    public double getMoney() {
        return money;
    }

    public ArrayList<ItemEx> getItems() {
        return inventario;
    }

    public float getVolumeLimit() {
        return volumeLimit;
    }

    public void setVolumeLimit(float volumeLimit) {
        this.volumeLimit = volumeLimit;
    }
    
    public boolean canPay(double m) {
        return this.money >= m;
    }
    
    public boolean pay(double m) {
        if (this.money < m)
            return false;
        money -= m;
        return true;
    }
    
    public boolean addItem(Item it) {
        return addItem(it, 1);
    }
    
    public boolean addItem(Item it, int qtd) {
        //check if the item 'fits' in the inventory (volume limit)
        float dv = it.getVolume() * qtd;
        if (dv + invVolume > volumeLimit)
            return false;
        
        //add to mass and volume caches
        invVolume += dv;
        invMass += it.getMassa() * qtd;
        
        //add the item
        for (int i = 0; i < inventario.size(); i++)
            if (inventario.get(i).getItem().equals(it)) {
                inventario.get(i).add(qtd);
                return true;
            }
        inventario.add(new ItemEx(it, qtd, false, it.getIndicePreco()*100)); //default price
        return true;
    }
    
    public boolean removeItem(Item it) {
        return removeItem(it, 1);
    }
    
    public boolean removeItem(Item it, int qtd) {
        for (int i = 0; i < inventario.size(); i++)
            if (inventario.get(i).getItem().equals(it)) {
                if (inventario.get(i).getQtd() < qtd)
                    return false;
                inventario.get(i).add(-qtd);
                invMass -= inventario.get(i).getItem().getMassa() * qtd;
                invVolume -= inventario.get(i).getItem().getVolume() * qtd;
                if (inventario.get(i).getQtd() == 0)
                    inventario.remove(i);
                return true;
            }
        return false;
    }
    
    public int qtosItems(Item it) {
        for (int i = 0; i < inventario.size(); i++)
            if (inventario.get(i).getItem().equals(it))
                return inventario.get(i).getQtd();
        return 0;
    }
    
    public boolean possue(Item it) {
        for (int i = 0; i < inventario.size(); i++)
            if (inventario.get(i).getItem().equals(it))
                return true;
        return false;
    }
    
    public static class ItemInv {
        private Item item;
        private int qtd;
        
        protected ItemInv() {}

        public ItemInv(Item item, int qtd) {
            this.item = item;
            this.qtd = qtd;
        }

        public Item getItem() {
            return item;
        }

        public int getQtd() {
            return qtd;
        }

        public void add(int v) {
            this.qtd += v;
        }
    }
    
    public static class ItemEx extends ItemInv {

        private boolean locked;
        private double cost;
        
        private ItemEx() {}
        
        public ItemEx(Item item, int qtd) {
            this(item, qtd, false, 0);
        }
        
        public ItemEx(Item i) {
            this(new ItemInv(i, 1));
        }

        public ItemEx(ItemInv i) {
            this(i.getItem(), i.getQtd(), false, 0);
        }

        public ItemEx(Item item, int qtd, boolean locked, double cost) {
            super(item, qtd);
            this.locked = locked;
            this.cost = cost;
        }

        public double getCost() {
            return cost;
        }

        public boolean isLocked() {
            return locked;
        }

        public void setLocked(boolean locked) {
            this.locked = locked;
        }

        public void setCost(double cost) {
            this.cost = cost;
        }
    }
}
